{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "3418e1c4-390c-4d91-9845-20bd4521a0e7",
   "metadata": {},
   "source": [
    "# Interactivity Options\n",
    "\n",
    "::: {note}\n",
    "These options only apply to the interactive plotting backends (e.g. [Bokeh](plot-ext-bokeh)), not to the static backend [Matplotlib](plot-ext-matplotlib).\n",
    ":::\n",
    "\n",
    "Bokeh specific options for adding hover tools as well as other interactive tools like tap tool and box select tool:\n",
    "\n",
    "```{eval-rst}\n",
    ".. plotting-options-table:: Interactivity Options\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "111051e1-7835-471f-a30f-f46d17194d3a",
   "metadata": {},
   "source": [
    "(option-hover)=\n",
    "## `hover`\n",
    "\n",
    "Enables or disables hover tooltips on the plot, also accepts `'hline'` and `'vline'` to change the hit-testing mode.\n",
    "\n",
    "::: {note}\n",
    "This option is `True` by default for most plots, but is automatically set to `False` when [`datashade=True`](option-datashade) and [`selector`](option-selector) is not set, since no relevant data can be displayed as HoloViews returns to the front-end an RGB element that doesn’t include the aggregated data. If you’re using `datashade=True` and still want interactivity, consider alternatives like using [`rasterize=True`](option-rasterize), combining `datashade` with [`dynspread`](option-dynspread), or enabling [`resample_when`](option-resample_when).\n",
    ":::\n",
    "\n",
    "::: {note}\n",
    "- `errorbars` plots: Hover is always disabled because Bokeh’s annotation glyphs (used for error bars) don’t support hover interaction.\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "da0bfb04-d546-4bad-bd34-3a9ba17fbcd7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "opts = dict(\n",
    "    x='bill_length_mm', y='bill_depth_mm',\n",
    "    by='species', frame_width=250,\n",
    ")\n",
    "plot1 = df.hvplot.scatter(title='Scatter with hover tool (Default)', **opts)\n",
    "plot2 = df.hvplot.scatter(hover=False, title='Scatter without hover tool', **opts)\n",
    "plot1 + plot2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0bd3d86b-b390-4193-97eb-74d67e212f62",
   "metadata": {},
   "source": [
    "Particularly useful for time series plots, `hover='vline'` displays tooltips with data collected from points that intersect vertically with the cursor."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c3e57a8f-b94a-4182-a3ea-7f7aab15199d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\").set_index(\"date\")[\"Apple\"]\n",
    "\n",
    "df.hvplot.line(hover=\"vline\", title=\"hover with vline mode\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "30839bfb-e814-42d8-bac6-d61b5b84cead",
   "metadata": {},
   "source": [
    "(option-hover_cols)=\n",
    "## `hover_cols`\n",
    "\n",
    "Specifies additional columns from the dataset to be shown in the hover tooltip.\n",
    "- Accepts a list of column names, a single column name as a string, or 'all' to include all available columns.\n",
    "- When set to 'all', it includes index columns only if [`use_index=True`](option-use_index).\n",
    "\n",
    "::: {note} \n",
    "`hover_cols` complements the default dimensions shown in the tooltip but does not override them.\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "028678e4-0bbf-4eee-b39e-7aef71f1de2f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "opts = dict(\n",
    "    x='bill_length_mm', y='bill_depth_mm',\n",
    "    by='species', frame_width=250,\n",
    ")\n",
    "plot1 = df.hvplot.scatter(title='Default hover_cols', **opts)\n",
    "plot2 = df.hvplot.scatter(\n",
    "    hover_cols=['sex', 'body_mass_g'], title='Additional hover columns', **opts\n",
    ")\n",
    "plot3 = df.hvplot.scatter(\n",
    "    hover_cols='all', title='All hover columns', **opts\n",
    ")\n",
    "\n",
    "plot4 = df.hvplot.scatter(\n",
    "    hover_cols='all',\n",
    "    use_index=False,\n",
    "    title='All hover columns without index',\n",
    "    **opts\n",
    ")\n",
    "(plot1 + plot2 + plot3 + plot4).cols(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2560fd13-ccc7-4be1-805f-08f60912c487",
   "metadata": {},
   "source": [
    "Hover on the points in each of the examples to see the displayed hover information."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb86944e-467a-4c01-a9b5-46cf09a0bb63",
   "metadata": {},
   "source": [
    "(option-hover_tooltips)=\n",
    "## `hover_tooltips`\n",
    "\n",
    "Controls the contents and layout of the hover tooltip using a list of tooltips. Each tooltip is a 2-tuple like `(\"label\", \"@<column_name>\")` used for specifying the name and format of the hover tooltip.\n",
    "\n",
    "Formatting options in the tooltips can be one of:\n",
    "\n",
    "- numeral format – for abbreviated numbers (e.g. 1k, 3.2M)\n",
    "- datetime format – for date/time values\n",
    "- printf format – for precision control like \"%.2f\"\n",
    "\n",
    "If set, it overrides the default auto-generated tooltips.\n",
    "\n",
    "::: {tip} \n",
    "Be sure to use @-prefixed dimension names inside each tooltip for the dimension names.\n",
    ":::\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "df7a80d9-db4c-4353-9b61-2a274b9fbe04",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\")\n",
    "\n",
    "opts = dict(\n",
    "    x='date', frame_width=250,\n",
    "    group_label=\"Company\" # rename group label\n",
    ")\n",
    "plot1 = df.hvplot.line(**opts, title=\"Default hover tooltips\")\n",
    "plot2 = df.hvplot.line(\n",
    "    hover_tooltips=[\n",
    "        (\"Company\", \"@Company\"), # No formatting\n",
    "        (\"Date\", \"@date{%b %Y}\"), # datetime format to Month Year style\n",
    "        (\"Price\", \"@value{$0.0f}\"), # printf format to 2 decimal\n",
    "    ],\n",
    "    title=\"Customized hover tooltips\",\n",
    "    **opts\n",
    ")\n",
    "plot1 + plot2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "069d4a51-b1bf-41ee-ade3-9a5d8a65f935",
   "metadata": {},
   "source": [
    "::: {seealso}\n",
    "See [`bokeh formatters`](https://docs.bokeh.org/en/latest/docs/user_guide/interaction/tools.html#formatting-tooltip-fields) for more information about formatting the tooltips.\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b51e3c5d-39eb-4273-92b5-80a8f6456063",
   "metadata": {},
   "source": [
    "(option-toolbar)=\n",
    "## `toolbar`\n",
    "\n",
    "This option controls whether the toolbar should be displayed and its location."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3fd67472-c3d2-4029-9b10-22e0ccd2ef89",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"y\": [1, 4, 2]})\n",
    "\n",
    "df.hvplot.scatter(toolbar=\"right\", title=\"toolbar=right (default)\", height=250, width=400)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5e6d4af3-faf1-4428-8000-5e54a0bac0de",
   "metadata": {},
   "outputs": [],
   "source": [
    "df.hvplot.scatter(toolbar=\"left\", title=\"toolbar=left\", height=250, width=400)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "31fb3e14-b0a9-440f-a290-a70688ea1082",
   "metadata": {},
   "outputs": [],
   "source": [
    "df.hvplot.scatter(toolbar=\"above\", title=\"toolbar=above\", height=150, width=400)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "268cb125-5031-4ec7-9c34-4be67361f928",
   "metadata": {},
   "outputs": [],
   "source": [
    "df.hvplot.scatter(toolbar=\"below\", title=\"toolbar=below\", height=150, width=400)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ebeff528-e94a-47b2-af4d-56817d4fdb36",
   "metadata": {},
   "outputs": [],
   "source": [
    "df.hvplot.scatter(toolbar=None, title=\"toolbar=None\", height=150, width=400)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25131ffd-e624-4a9d-b46a-8178e0728fbf",
   "metadata": {},
   "source": [
    "In a layout, a unique toolbar is displayed above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e6745031-7dc8-42ba-ae83-e30a3b2db2cf",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"y\": [1, 4, 2]})\n",
    "\n",
    "df.hvplot.scatter(width=300, height=150) + df.hvplot.line(width=300, height=150)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5368a527-98aa-4e15-b2b0-3fad92ec5e59",
   "metadata": {},
   "source": [
    "To control the toolbar, call `.opts(toolbar=...)` on the layout object with one of `'above'`, `'below'`, `'left'`, `'right'`, or `'None'` (to disable it)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9e86c94b-9891-48d0-b0ab-5e6cce4ee06a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"y\": [1, 4, 2]})\n",
    "\n",
    "layout = df.hvplot.scatter(width=300, height=150) + df.hvplot.line(width=300, height=150)\n",
    "layout.opts(toolbar=\"below\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62efae26-66fb-40e2-8374-1be7b3636b20",
   "metadata": {},
   "source": [
    "(option-autohide_toolbar)=\n",
    "## `autohide_toolbar`\n",
    "\n",
    "By default the Bokeh toolbar is always displayed. This option allows to automatically hide the toolbar when the plot is not hovered."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6f99d509-ec86-4664-9c33-afb817487672",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"y\": [1, 4, 2]})\n",
    "\n",
    "df.hvplot.scatter(autohide_toolbar=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "06ed84b3-a552-4bb1-8d17-64bcf32086f7",
   "metadata": {},
   "source": [
    "In order to enable this option globally, add this snippet to your code:\n",
    "\n",
    "```python\n",
    "import holoviews as hv\n",
    "\n",
    "hv.plotting.bokeh.plot.BokehPlot.autohide_toolbar = True\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a1fc016-b6bd-4ba9-bbbd-3a06660c93a8",
   "metadata": {},
   "source": [
    "(option-tools)=\n",
    "## `tools`\n",
    "A list of interactive tools to enable on the plot. These are Bokeh tool names or tool instances (e.g., `tap`, `box_select`, or `HoverTool()`). \n",
    "\n",
    "Tools typically appear as a vertical toolbar on the right-hand side of the plot. Common options include:\n",
    "- `hover` – show tooltips\n",
    "- `tap` – click to select points\n",
    "- `box_select`, `lasso_select` – select a region\n",
    "- `wheel_zoom`, `pan`, `reset` – for navigation\n",
    "\n",
    "The `hover` tool is automatically added by default when not already in `tools`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ca916ac3-b5be-4add-aa35-7995fa6ad7d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.penguins(\"pandas\")\n",
    "\n",
    "df.hvplot.scatter(\n",
    "    x='bill_length_mm', y='bill_depth_mm',\n",
    "    tools=['tap', 'lasso_select'],\n",
    "    title='Interactive plot with additional tools'\n",
    ")"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
